<?php

namespace yphp;

/**
 * 路由分析
 */
class Request extends Instance
{
    //构造函数，初始化路由
    function construct()
    {
        $scriptName = $_SERVER['SCRIPT_NAME'];
        # 获取/最后一次出现的位置
        $index = strrpos($scriptName, '/');
        // 前缀URL目录：前端、后端
        define('WEB_PRE', substr($scriptName, 0, $index));
        define('PHP_PRE', Config::web('rewrite') ? WEB_PRE : $scriptName);
        $this->uri = $this->getRequestUri();
        $uri = preg_replace('/\.html$/', '', preg_replace("/^(\/[^\?&#]+)?.*?$/", '\1', $this->uri));
        $len = strlen($scriptName);
        $start = substr($uri, 0, $len) === $scriptName ? $len : $index;
        $this->path = substr($uri, $start) ?: '/';
        $this->protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')) ? 'https://' : 'http://';
        $this->host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
        $this->url = $this->protocol . $this->host . $this->uri;
        $this->method = $_SERVER['REQUEST_METHOD'];
        $this->isAjax = $this->Ajax();
        $this->get = $_GET;
        $this->post = $_POST;
        $this->param = $_REQUEST;
        $this->files = $_FILES;
        return self::single();
    }

    // post方法
    function post($key = null,$default = null)
    {
        return is_null($key) ? $this->post : (key_exists($key,$this->post) ? $this->post[$key] : $default);
    }

    function filterPost($key = null, $type = 'htmlspecialchars', $default = null)
    {
        return call_user_func([$this, $type], $this->post($key, $default));
    }

    function htmlspecialchars($arr) {
        if (is_array($arr)) {
            foreach ($arr as $key => $value) {
                $arr[$key] = $this->htmlspecialchars($value);
            }
            return $arr;
        } else {
            return is_string($arr) ? htmlspecialchars($arr) : null;
        }
    }

    function addslashes($arr) {
        if (is_array($arr)) {
            foreach ($arr as $key => $value) {
                $arr[$key] = $this->addslashes($value);
            }
            return $arr;
        } else {
            return is_string($arr) ? addslashes($arr) : null;
        }
    }

    function filterString($arr) {
        if (is_array($arr)) {
            foreach ($arr as $key => $value) {
                $arr[$key] = $this->filterString($value);
            }
            return $arr;
        } else {
            return is_string($arr) ? addslashes(htmlspecialchars($arr)) : null;
        }
    }

    // get方法
    function get($key = null,$default = null)
    {
        return is_null($key) ? $this->get : (key_exists($key,$this->get) ? $this->get[$key] : $default);
    }

    function filterGet($key = null, $type = 'htmlspecialchars', $default = null)
    {
        return call_user_func([$this, $type], $this->get($key, $default));
    }

    // param方法
    function param($key = null,$default = null)
    {
        return is_null($key) ? $this->param : (key_exists($key,$this->param) ? $this->param[$key] : $default);
    }

    function filterParam($key = null, $type = 'htmlspecialchars', $default = null)
    {
        return call_user_func([$this, $type], $this->param($key, $default));
    }

    // 获取REQUEST_URI
    private function getRequestUri()
    {
        if (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
            // check this first so IIS will catch
            $requestUri = $_SERVER['HTTP_X_REWRITE_URL'];
        } elseif (isset($_SERVER['REDIRECT_URL'])) {
            // Check if using mod_rewrite
            $requestUri = $_SERVER['REDIRECT_URL'];
        } elseif (isset($_SERVER['REQUEST_URI'])) {
            $requestUri = $_SERVER['REQUEST_URI'];
        } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
            // IIS 5.0, PHP as CGI
            $requestUri = $_SERVER['ORIG_PATH_INFO'];
            if (!empty($_SERVER['QUERY_STRING'])) {
                $requestUri .= '?' . $_SERVER['QUERY_STRING'];
            }
        }
        return $requestUri;
    }

    // 是否是ajax请求
    private function Ajax()
    {
        $state = false;
        if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'){
            $state = true;
        } else {
            list($key,$val) = Safe::showAjax();
            if(key_exists($key,$_REQUEST)){
                if(is_null($val)){
                    $state = true;
                } else {
                    $_REQUEST[$key] === $val && $state = true;
                }
            }
        }
        return $state;
    }

    //+----------------------------------------------------------------------
    //  判断是否移动端
    //+----------------------------------------------------------------------

    private $mobile;

    function mobile()
    {
        if (is_null($this->mobile)) {
            if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
                return true;
            }
            if (isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], 'wap')) {
                return true;
            }
            if (isset($_SERVER['HTTP_USER_AGENT'])) {
                $p = 'nokia|sony|ericsson|mot|samsung|htc|sgh|lg|sharp|sie-|philips|panasonic|alcatel|lenovo|iphone|ipod|blackberry|meizu|android|netfront|symbian|ucweb|windowsce|palm|operamini|operamobi|openwave|nexusone|cldc|midp|wap|mobile|phone';
                if (preg_match("/(" . $p . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
                    return true;
                }
            }
            if (isset($_SERVER['HTTP_ACCEPT'])) {
                if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
                    return true;
                }
            }
            return false;
        }
        return $this->mobile;
    }

    //+----------------------------------------------------------------------
    //  请求方式
    //+----------------------------------------------------------------------

    private $method;

    function method()
    {
        return $this->method;
    }

    // 是否是post访问
    function isPost()
    {
        return $this->method() === 'POST';
    }

    // 是否是get访问
    function isGet()
    {
        return $this->method() === 'GET';
    }

    private $isAjax;

    // 是否ajax请求
    function isAjax()
    {
        return $this->isAjax;
    }


    // 获取关键路由
    function __call($name, $arguments)
    {
        if(!property_exists($this,$name)) throw new \Exception('Requetst对象不存在'.$name.'方法不存在');
        return $this->$name;
    }

}